#include "CentralDirectory.h"

CentralDirectory::CentralDirectory(FileHeader* header)
{
    this->fileHeaderSignature_ = CENTRAL_DIRECTORY_SIGNATURE;
    this->versionMadeBy_ = 0;
    this->versionNedded_ = 10;
    this->flag_ = 0;
    this->compressionMethod_ = 0;
    this->lastModificationTime_ = header->lastModifiedTime_;
    this->lastModificationDate_ = header->lastModifiedDate_;
    this->crc_ = header->crc_;
    this->compressedSize_ = header->compressedSize_;
    this->uncompressedSize_ = header->unCompressedSize_;
    this->fileNameLength_ = header->fileNameLength_;
    this->extraFieldLength_ = header->extraFieldLength_;
    this->fileCommentLength_ = 0;
    this->diskNumber_ = 0;
    this->internalFileAttributes_ = 0;
    this->externalFileAttributes_ = 0;
    this->relativeOffset_ = 0;
    this->fileName_ = new char[header->fileNameLength_];
    memcpy(this->fileName_, header->fileName_, header->fileNameLength_);
    this->extraField_ = new char[header->extraFieldLength_];
    memcpy(this->extraField_, header->extraField_, header->extraFieldLength_);
    this->fileComment_ = 0;
}

CentralDirectory::CentralDirectory(CentralDirectory* other)
{
    this->fileHeaderSignature_ = other->fileHeaderSignature_;
    this->versionMadeBy_ = other->versionMadeBy_;
    this->versionNedded_ = other->versionNedded_;
    this->flag_ = other->flag_;
    this->compressionMethod_ = other->compressionMethod_;
    this->lastModificationTime_ = other->lastModificationTime_;
    this->lastModificationDate_ = other->lastModificationDate_;
    this->crc_ = other->crc_;
    this->compressedSize_ = other->compressedSize_;
    this->uncompressedSize_ = other->uncompressedSize_;
    this->fileNameLength_ = other->fileNameLength_;
    this->extraFieldLength_ = other->extraFieldLength_;
    this->fileCommentLength_ = other->fileCommentLength_;
    this->diskNumber_ = other->diskNumber_;
    this->internalFileAttributes_ = other->internalFileAttributes_;
    this->externalFileAttributes_ = other->externalFileAttributes_;
    this->relativeOffset_ = other->relativeOffset_;
    this->fileName_ = new char[strlen(other->fileName_)];
    strcpy(this->fileName_, other->fileName_);
    this->extraField_ = new char[strlen(other->extraField_)];
    strcpy(this->extraField_, other->extraField_);
    this->fileComment_ = new char[this->fileCommentLength_];
    strcpy(this->fileComment_, other->fileComment_);
}

CentralDirectory::~CentralDirectory()
{
    if(this->fileName_)
        delete [] this->fileName_;
    if(this->extraField_)
        delete [] this->extraField_;
    if(this->fileComment_)
        delete [] this->fileComment_;
}

int CentralDirectory::size()
{
    return 46 + this->fileCommentLength_ + this->fileNameLength_ + this->extraFieldLength_;
}

std::ostream& operator<<(std::ostream& out, CentralDirectory& centralDirectory)
{
    out.write((char*) &centralDirectory.fileHeaderSignature_, 4);
    out.write((char*) &centralDirectory.versionMadeBy_, 2);
    out.write((char*) &centralDirectory.versionNedded_, 2);
    out.write((char*) &centralDirectory.flag_, 2);
    out.write((char*) &centralDirectory.compressionMethod_, 2);
    out.write((char*) &centralDirectory.lastModificationTime_, 2);
    out.write((char*) &centralDirectory.lastModificationDate_, 2);
    out.write((char*) &centralDirectory.crc_, 4);
    out.write((char*) &centralDirectory.compressedSize_, 4);
    out.write((char*) &centralDirectory.uncompressedSize_, 4);
    out.write((char*) &centralDirectory.fileNameLength_, 2);
    out.write((char*) &centralDirectory.extraFieldLength_, 2);
    out.write((char*) &centralDirectory.fileCommentLength_, 2);
    out.write((char*) &centralDirectory.diskNumber_, 2);
    out.write((char*) &centralDirectory.internalFileAttributes_, 2);
    out.write((char*) &centralDirectory.externalFileAttributes_, 4);
    out.write((char*) &centralDirectory.relativeOffset_, 4);
    out.write(centralDirectory.fileName_, centralDirectory.fileNameLength_);
    out.write(centralDirectory.extraField_, centralDirectory.extraFieldLength_);
    out.write(centralDirectory.fileComment_, centralDirectory.fileCommentLength_);
    
    return out;
}